﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include <vector>

#include "GcmpModelInterface.h"
#include "IDbObject.h"
#include "OwnerPtr.h"
#include "ParameterProcessType.h"
#include "ParameterStorageType.h"
#include "PointTypes.h"
#include "Color.h"

namespace gcmp {
    class Coordinate3d;
    class IDocument;
    class IParameterCustomData;
    class IParameterValueStorage;
    class IParameterDefinition;
    class IParameterOverride;
    class IParameterValidator;
    class UniIdentity;
    class ICurve3d;
    class ICurve2d;
    class IPolyCurve;
    class IGeometry;

    /// \brief 参数的标志属性集
    struct ParameterAttributes
    {
        bool IsTypeParameter; ///< 是否是类型参数
        bool IsDriveParameter; ///< 是否是驱动参数 
        bool IsUserVisible; ///< 是否用户可见参数
    };

    static ParameterAttributes DefaultParameterAttributes = {false, false, true};

    /// \brief 参数类
    class GCMP_MODEL_INTERFACE_EXPORT IParameter : public IDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IParameter, gcmp::IDbObject)
    public:
#pragma region 静态构造方法，供外部使用
        /// \brief 新建参数
        ///
        /// \param pDocument 参数所属文档
        /// \param storageType 参数的存储类型
        /// \param parameterAttributes 参数的标志属性集
        /// \param parameterDefinitionUid 参数的Uid
        /// \param processType 参数的处理类型
        /// \return 新创建的参数
        static OwnerPtr<IParameter> CreateParameter(IDocument* pDocument, ParameterStorageType storageType,
            const ParameterAttributes& parameterAttributes, const UniIdentity& parameterDefinitionUid, 
            ParameterProcessType processType);

        /// \brief 新建无效参数
        ///
        /// \return 新创建的参数
        static OwnerPtr<IParameter> CreateInvalidParameter();

        /// \brief 判断参数是否是有效参数
        ///
        /// \return 如果是有效参数返回true，否则false。
        static bool IsValidParameter(const OwnerPtr<IParameter>& opParam);
#pragma endregion

#pragma region 参数定义的Id和Uid
        /// \brief 获取参数定义
        ///
        /// \return 参数定义
        virtual const IParameterDefinition* GetParameterDefinition() const = 0;

        /// \brief 获取参数定义在一个文档内的Id
         ///
         /// Id为Int32类型，在文档内唯一，并且只有在参数加入文档后有效
         /// \return 参数定义Id
        virtual Int32 GetParameterDefinitionId() const = 0;

        /// \brief 获取参数定义的跨文档Uid
        ///
        /// \return 参数定义的跨文档Uid
        virtual const UniIdentity& GetParameterDefinitionUid() const = 0;

        /// \brief 设置参数定义的跨文档Uid
        ///
        /// \param uid 参数定义的跨文档Uid
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetParameterDefinitionUid(const UniIdentity& uid) = 0;
#pragma endregion

#pragma region 参数内存储的参数值相关接口

        /// \brief 获取只读参数值存储对象
        ///
        /// \return 只读参数值存储对象
        virtual const IParameterValueStorage* GetParameterValueStorage() const = 0;

        /// \brief 获取可写参数值存储对象
        ///
        /// \return 可写参数值存储对象
        virtual IParameterValueStorage* GetParameterValueStorageFw() = 0;

        /// \brief 通过参数值存储对象设置参数值
        ///
        /// \param opParameterValueStorage 参数值存储对象
        /// \return 如果设置成功返回true，否则返回false
        virtual  bool SetParameterValueStorage(OwnerPtr<IParameterValueStorage> opParameterValueStorage) = 0;

        /// \brief 获取String类型参数值
        ///
        /// \return String类型参数值
        virtual const std::wstring& GetValueAsString() const = 0;

        /// \brief 设置String类型参数值
        ///
        /// \param value String类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsString(const std::wstring& value) = 0;

        /// \brief 获取bool类型参数值
        ///
        /// \return bool类型参数值
        virtual bool GetValueAsBool() const = 0;

        /// \brief 设置bool类型参数值
        ///
        /// \param value bool类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsBool(bool value) = 0;

        /// \brief 获取double类型参数值
        ///
        /// \return double类型参数值
        virtual double GetValueAsDouble() const = 0;

        /// \brief 设置double类型参数值
        ///
        /// \param value double类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsDouble(double value) = 0;

        // \brief 获取int类型参数值
        ///
        /// \return int类型参数值
        virtual int GetValueAsInt() const = 0;

        /// \brief 设置int类型参数值
        ///
        /// \param value int类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsInt(int value) = 0;

        /// \brief 获取ElementId类型参数值
        ///
        /// \return ElementId类型参数值
        virtual ElementId GetValueAsElementId() const = 0;

        /// \brief 设置ElementId类型参数值
        ///
        /// \param value ElementId类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsElementId(const ElementId& value) = 0;

        /// \brief 设置自定义参数类型数据对象
        /// \param 自定义参数对象
        /// \return 如果设置成功返回true，否则返回false
        virtual  bool SetValueAsCustomData(OwnerPtr<IParameterCustomData> opCutsomData) = 0;

        /// \brief 获取自定义参数类型数据对象
        /// \return 自定义类型的数据对象
        virtual  const IParameterCustomData* GetValueAsCustomData() const = 0;

        /// \brief 获取Color类型参数值
        ///
        /// \return Color 类型参数值
        virtual Color GetValueAsColor() const = 0;

        /// \brief 设置Color类型参数值
        ///
        /// \param value Color 类型参数值
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsColor(const Color& value) = 0;

        /// \brief 设置几何参数类型数据对象
        /// \param 几何参数对象
        /// \return 如果设置成功返回true，否则返回false
        virtual  bool SetValueAsGeometry(OwnerPtr<IGeometry> opGeometry) = 0;

        /// \brief 获取几何参数类型数据对象
        /// \return 几何类型的数据对象
        virtual  const IGeometry* GetValueAsGeometry() const = 0;

        /// \brief 设置Guid参数类型数据对象
        /// \param Guid参数对象
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetValueAsGuid(const Guid& value) = 0;

        /// \brief 获取Guid类型参数值
        /// \return Guid 类型参数值
        virtual Guid GetValueAsGuid() const = 0;

#pragma endregion

#pragma region 参数的一些其他属性
        /// \brief 获取当前参数是否为type类型参数
        ///
        /// \return 如果是type类型参数返回true，否则返回false
        virtual bool IsTypeParameter() const = 0;

        /// \brief 设置当前参数是否为type类型参数
        /// \param 是否为type类型参数的标志
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetTypeParameter(bool theValue) = 0;

        /// \brief 获取当前参数是否为绑定参数
        ///
        /// \return 如果是绑定参数返回true，否则返回false
        virtual bool IsBoundParameter() const = 0;

        /// \brief 设置参数是否可绑定。
        ///
        /// \param isBindable 是否可绑定
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetBindable(bool isBindable) = 0;

        /// \brief 获取当前参数是否可绑定
        ///
        /// \return 如果当前参数可以绑定返回true，否则返回false
        virtual bool IsBindable() const = 0;

        /// \brief 获取当前参数的参数处理类型
        ///
        /// \return 参数处理类型
        virtual  ParameterProcessType GetParameterProcessType() const = 0;

        /// \brief 设置当前参数的处理类型
        ///
        /// \param parameterProcessType 参数处理类型
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetParameterProcessType(ParameterProcessType parameterProcessType) = 0;

        /// \brief 获取当前参数是否为驱动参数
        ///
        /// \return 如果是驱动参数返回true，否则返回false
        virtual bool IsDriveParameter() const = 0;

        /// \brief 设置当前参数是否为驱动参数
        ///
        /// \param value 是否为驱动参数
        /// \return 如果设置成功返回true，否则返回false
        virtual bool SetDriveParameter(bool value) = 0;

        /// \brief 判断此参数是否为有效参数
        ///
        /// \return 如果是有效参数返回true，否则返回false
        virtual  bool IsValidDocumentParameter() const = 0;

        /// \brief 返回当前参数是否为输入参数
        ///
        /// \return 如果是输入参数返回true，否则返回false
        virtual bool IsInputParameter() const = 0;

        /// \brief 返回当前参数是否为输出参数
        ///
        /// \return 如果是输出参数返回true，否则返回false
        virtual  bool IsOutputParameter() const = 0;

        /// \brief 返回文档指针
        ///
        /// \return 文档指针
        virtual const IDocument* GetDocument() const = 0;

        /// \brief 设置文档指针
        ///
        /// \param 文档指针
        virtual void SetDocument(IDocument* pDocument) = 0;

        /// \brief 获取参数的名字
        ///
        /// 如果没有定制过，和Definition的名字一样
        /// \return std::wstring 名字
        virtual std::wstring GetName() const = 0;

        /// \brief 获取参数的验证器
        ///
        /// 如果没有设置, 则返回nullptr
        /// \return IParameterValidator* 验证器
        virtual const IParameterValidator* GetValidator() const = 0;

        /// \brief 克隆一个同样的参数
        ///
        /// \return 新的克隆参数
        virtual  OwnerPtr<IParameter> Clone() const = 0;

        /// \brief 判断当前参数是否和输入参数有相同的属性值
        /// \param 待比较的输入参数
        /// \return 如果相同返回true，否则返回false
        virtual bool HasSameValue(const IParameter* pOther) const = 0;

        /// \brief 返回当前参数是否可修改
        /// \return 可修改返回true，否则false
        virtual bool IsModifiable() const = 0;

        /// \brief 返回当前参数是否是用户可见
        /// \return 如果是用户可见，返回true，否则false
        virtual bool IsUserVisible() const = 0;

        /// \brief 返回当前参数是否是几何参数
        ///
        /// \return 如果是几何参数，返回true，否则false
        virtual bool IsGeometricParameter() const = 0;

#pragma endregion
    };
}


